/**
 * 判断对象是否为空 (
 *
 * - 对象本身=null/undefined、
 * - 字符串长度=0、
 * - 数组/Map/Set元素数量=0、
 * - object一个属性都没有或者所有属性值都=null/undefined
 *
 * )
 * @param o
 */
function isEmpty<T>(o: T): boolean {
  if (o == null || (o as any as string) === "") {
    return true;
  }
  if (Array.isArray(o)) {
    return o.length === 0;
  }
  if (o instanceof Map || o instanceof Set) {
    return o.size === 0;
  }

  if (typeof o === "object") {
    const keys = Object.keys(o) as (keyof typeof o)[];
    return keys.length === 0 || keys.filter(k => o[k] != null).length === 0;
  }

  return false;
}

/**
 * 判断对象不为空
 * @see isEmpty
 * @param o
 */
function isNotEmpty<T>(o: T): o is NonNullable<T> {
  return !isEmpty(o);
}

const Validates = {
  isEmpty,
  isNotEmpty,
};

export default Validates;

export function isNull<T>(o: T | null | undefined): o is null {
  return o == null;
}

export function isNotNull<T>(o: T | null | undefined): o is T {
  return o != null;
}
